﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.ServiceManagement;
using Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.ServiceManagement.Contracts;
using Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.ServiceModel;
using Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling;
using System.Security.Cryptography.X509Certificates;
using System.Xml.Linq;

namespace LoadController
{
    public class AutoScaler
    {
        private Subscription subscription;
        private HostedService hostedService;

        public AutoScaler()
        {
            subscription = new Subscription(AppSettings.AutoScaler_subscriptionname,
                                            new Guid(AppSettings.AutoScaler_subscriptionid), 
                                            StoreName.My,
                                            StoreLocation.CurrentUser, 
                                            AppSettings.AutoScaler_managementcertificatethumbprint);

            hostedService = new HostedService(AppSettings.AutoScaler_hostedservicednsprefix,
                Microsoft.Practices.EnterpriseLibrary.WindowsAzure.Autoscaling.ServiceManagement.DeploymentSlot.Production,
                subscription);
        }

        private string ChangeConfiguration(string configuration, int count)
        {

            XDocument c = XDocument.Parse(GetStringFromBase64String(configuration));
            XNamespace ns = "http://schemas.microsoft.com/ServiceHosting/2008/10/ServiceConfiguration";
            XElement serviceConf = c.Element(ns + "ServiceConfiguration");

            dynamic role = serviceConf.Elements(ns + "Role").Where(r => r.Attribute("name").Value == AppSettings.AutoScaler_targetrolename).SingleOrDefault();

            role.Element(ns + "Instances").SetAttributeValue("count", count);

            return GetBase64StringFromString(serviceConf.ToString());
        }

        public ServiceDeployment getDeployment()
        {
             ServiceManagementClient smc = new ServiceManagementClient();
             return smc.GetDeployment(hostedService);
        }

        public string ChangeConfiguration(int instanceCount)
        {
            ServiceManagementClient smc = new ServiceManagementClient();
            ServiceDeployment deployment = smc.GetDeployment(hostedService);

            ChangeConfiguration configuration = new ChangeConfiguration();
            configuration.Configuration = ChangeConfiguration(deployment.Configuration, instanceCount);
            
            string requestID;

            if (deployment.Status == DeploymentStatus.Running)
                smc.ChangeConfiguration(hostedService, configuration, out requestID);
            else
                return "DeploymentStatus is not 'Running'";

            return requestID;
        }

        private string GetStringFromBase64String(string base64Str)
        {
            Byte[] bs  = System.Convert.FromBase64String(base64Str);
            string s = System.Text.Encoding.UTF8.GetString(bs);
            return s;
        }

        private string GetBase64StringFromString(string str)
        {
            Byte[] toEncodeAsBytes = System.Text.UTF8Encoding.UTF8.GetBytes(str);
            string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
            return returnValue;
        }
    }
}